; ********************************************************************************************************************
; * PSGOUT(SETUP,PLAY,TEMPO,TRK1,TRK2)
; ********************************************************************************************************************
FUNCTION	PSGOUT	PRG1,PRG2,PRG3,TRK1,TRK2
REM	; PSGOUT(P1,P2,P3,TRK1,TRK2)
REM	; P1 0=VECTORS   1=MUSIC  2=SFX  P2=PLAYMODE  P3=TEMPO
DEF	PRG1	BYTE
DEF	PRG2	BYTE
DEF	PRG3	BYTE
DEF	TRK1	WORD
DEF	TRK2	WORD
PRG1	FCB	0
PRG2	FCB	0
PRG3	FCB	0
TRK1	FCB	0,0
TRK2	FCB	0,0
INTERUPT	FCB	0,0
MAXVOL	FCB	0	;0=full
MAXSFXVOL	FCB	0	;0=full
VOL1	FCB	0	;volume
VOL2	FCB	0
VOL3	FCB	0
VOL4	FCB	0
SLEN1	FCB	0	;delay length
SLEN2	FCB	0
SLEN3	FCB	0
SLEN4	FCB	0
SCNT1	FCB	0	;delay cnt
SCNT2	FCB	0
SCNT3	FCB	0
SCNT4	FCB	0
CHAN1	FCB	8	;psg ports
CHAN2	FCB	9
CHAN3	FCB	10
CHAN4	FCB	10
	FCB	0
; 1= setup and play as loop will =2 after      3=setup and play once
PLAY	FCB	0	;play the song
PLYSPD	FCB	2	;delay tempo
PLYCNT	FCB	0	;counter
PLYSFXPOS	FCB	0,0	;sfx pos
PLYSFXSTR	FCB	0,0	;sfx start
PLYSFXSPD	FCB	0	;speed
PLYSFXCNT	FCB	0	;delay
PLYSFXLEN	FCB	0
PLYSFXOCT	FCB	3
PLYSFXENC	FCB	0
PLYSFXDEL	FCB	0
PLAYSFX	FCB	0	;run?
PLYPOS1	FCB	0,0
PLYSTR1	FCB	0,0
PLYPOS2	FCB	0,0
PLYSTR2	FCB	0,0
PLYOCT1	FCB	3
PLYLEN1	FCB	0
PLYENC1	FCB	0	;channel 1 delay
PLYDEL1	FCB	0	;pause counter
PLYOCT2	FCB	3
PLYLEN2	FCB	0
PLYENC2	FCB	0	;channel 2 delay
PLYDEL2	FCB	0	;pause counter
TEMP	FCB	0
TEMPA	FCB	0
TEMPB	FCB	0	;temp data
NOTE	FCB	0,0
SLOT	FCB	0
BSLOT	FCB	0
CARTSEL	FCB	0
FINDPSG	FCB	0
#NOMOVE
YMCTRL	EQU	$FF5D	;yamaha control register
YMMEM	EQU	$FF5A	;mem bank setting 0
YMREG	EQU	$FF5E
YMDATA	EQU	$FF5F
NOTETB2	FCB	1,2,3,4,6,8,12,16,32
NOTETB1	FCB	9,11,0,2,4,5,7,9
VOLUMETB	FCB	15,14,12,10,8,6,4,2,1,0
;
PSGDAT	FCB	15,255,15,209,14,239,14,24,13,77,12,142,11,218,11,48,10,143,9,247,9,104
	FCB	8,225,8,97,7,233,7,119,7,12,6,167,6,71,5,237,5,152,5,71,4,252,4,180,4,112
	FCB	4,49,3,244,3,188,3,134,3,83,3,36,2,246,2,204,2,164,2,126,2,90,2,56,2,24,1,250
	FCB	1,222,1,195,1,170,1,146,1,123,1,102,1,82,1,63,1,45,1,28,1,12,0,253,0,239,0,225
	FCB	0,213,0,201,0,190,0,179,0,169,0,159,0,150,0,142,0,134,0,127,0,119,0,113,0,106
	FCB	0,100,0,95,0,89,0,84,0,80,0,75,0,71,0,67,0,63,0,60,0,56,0,53,0,50,0,47,0,45,0,42
	FCB	0,40,0,38,0,36,0,34,0,32,0,30,0,28,0,27,0,25,0,24,0,22,0,21,0,20,0,19,0,18,0,17,0,16
	FCB	255,255	;ctrl bytes to make sure im not out of range
;
#MOVE
PSGOUT	LDA	PRG1
	CMPA	#0
	LBEQ	SETUPVECTORS
	CMPA	#1
	LBEQ	SETUPMUSIC	;SETUP IRQ ONLY ONCE IN YOUR CODE
	CMPA	#2
	LBEQ	SETUPSFX	;SETUP SFX
	RTS
; ****************************************************GMCPLAY INTERUPT *********************************************
PSGPLAY	LDA	SLOT
	STA	$FF7F
	JSR	SILENCE
	JSR	PLAYMUSIC
	JSR	SFXPLAY
;	LDA	$FF02
;	RTI
	LDA	BSLOT
	STA	$FF7F
	JMP	[INTERUPT]
; ******************************************************SILENCE CHIP***********************************************************
SILENCE	CLRB
LOOPSIL	LDX	#VOL1
	LEAX	B,X
	LDA	8,X	;delay cnt
	BNE	SILEN
	LDA	4,X	;length
	STA	8,X
; lower the volume
	LDA	0,X
	CMPA	#15
	BHS	SILEN
	INC	,X
SILEN	LDA	8,X
	BEQ	SILEN2
	DEC	8,X
SILEN2	LDA	12,X	;chan
;	ADDA	,X  add volume
	STA	YMREG
	LDA	#15	;inverted from gmc
	SUBA	0,X
	STA	YMDATA
;	STA	$FF41
	INCB
	CMPB	#3	;dont use 4
	BLO	LOOPSIL
	RTS
; ***********************************************************SETUP SFX**************************************************
SETUPSFX	LDX	TRK1
	STX	PLYSFXPOS
	STX	PLYSFXSTR
	LDA	PRG3
	STA	PLYSFXSPD	;SPEED
	CLRA
	STA	PLYSFXCNT
	STA	PLYSFXLEN
	STA	PLYSFXENC
	STA	PLYSFXDEL
	LDA	PRG2
	STA	PLAYSFX
	RTS
; ********************************************SETUP THE MUSIC*********************************************************
SETUPMUSIC	LDX	TRK1
	STX	PLYPOS1
	STX	PLYSTR1
	LDX	TRK2
	STX	PLYPOS2
	STX	PLYSTR2
	LDA	PRG3
	STA	PLYSPD	;PLAYER TEMPO
	STA	PLYCNT	;CLEAR THE COUNTER
	LDA	#3
	STA	PLYOCT1
	STA	PLYOCT2
; clear all vars
	CLRA
	STA	PLYLEN1
	STA	PLYENC1
	STA	PLYDEL1
	STA	PLYLEN2
	STA	PLYENC2
	STA	PLYDEL2
	LDA	PRG2
	STA	PLAY
	RTS
; ****************************************SETUP IRQ VECTORS**********************************************************
SETUPVECTORS	
; basic setup end
	ORCC	#$50	;kill interupt
	LDD	$010D
	STD	INTERUPT
	LDX	#PSGPLAY
	STX	$010D
; mpi setup detect
; change for off rom
; use slot 1 for psg
; needs hard slot for rom
	LDA	$FF7F
	STA	BSLOT
	ANDA	#240
	STA	SLOT
	STA	$FF7F
	LDA	#7
	STA	YMREG
	LDA	#56
	STA	YMDATA
	LDA	BSLOT
	STA	$FF7F
ENABLETV	LDA	$FF23
	ORA	#8
	STA	$FF23
	LDA	$FF03
	ORA	#8
	STA	$FF03
	LDA	$FF01
	ORA	#8
	EORA	#8
	STA	$FF01
; done setup
; lets set play to 0 also
	CLR	PLAY
	CLR	PLAYSFX
	ANDCC	#$EF
	RTS
; ***************************************************PLAY THE MUSIC********************************************************
PLAYMUSIC	LDA	PLAY
	BNE	PLAYM	;check play routine
	RTS	;no music
PLAYM	LDA	PLYCNT
	BEQ	UPPLAY0
	DEC	PLYCNT
	RTS	;not ready to play
;
UPPLAY0	LDA	PLYSPD
	STA	PLYCNT	;delay reset
CHANNEL1	LDA	PLYDEL1
	CMPA	#1
	BLS	UPLP0	;good to go
	DEC	PLYDEL1
	LBRA	CHANNEL2
UPLP0	LDA	PLYENC1
	CMPA	#1
	BLS	UPPLAY00	;good to go
	DEC	PLYENC1
	LBRA	CHANNEL2
UPPLAY00	LDX	PLYPOS1
UPPLAY1	LDA	,X+	;grab command
; process string
	CMPA	#65
	LBLO	NOTMUSIC1
	CMPA	#71
	LBHI	NOTMUSIC1
; ok its a music tone
;
	SUBA	#65	0-11
; no hash tag
	LDY	#NOTETB1	;table for tones
	LEAY	A,Y	;get tone
	LDA	,Y	;tone loaded
; hash tag ?
	LDB	,X	;no advance
	CMPB	#35	;#
	BNE	NOHASH1
	INCA	;has a hash tag
	LEAX	1,X	;advance it
; load octave with it
NOHASH1	CMPB	#45
	BNE	NODECH1
	DECA	;has a -
	LEAX	1,X	;move player
NODECH1	STA	NOTE
	LDA	#12
	LDB	PLYOCT1
;	SUBB	#2  i dont think sub is needed on psg
	MUL
	SUBD	#10	;calibration
	LDY	#PSGDAT
	LEAY	D,Y
	LEAY	D,Y
; ok set the note
	LDA	NOTE
	LEAY	A,Y
	LEAY	A,Y	;twice
	LDA	,Y+	;first part of freq
; setup tone period
	LDB	#1
	STB	YMREG
	STA	YMDATA
	LDA	,Y	;next part
	DECB
	STB	YMREG
	STA	YMDATA	;tone set
	LDA	MAXVOL
	STA	VOL1
	LDA	#15
	SUBA	VOL1
	LDB	#8
	STB	YMREG
	STA	YMDATA	;set volume
	LDA	PLYLEN1
	STA	PLYENC1	;counter set
	LSRA
	STA	SLEN1	;smooth sound delay
	STA	SCNT1	;counter set
	STX	PLYPOS1	;save position
	LBRA	CHANNEL2
; exit
;
;
NOTMUSIC1	CMPA	#0
	BNE	CHKCMD1
	LDA	PLAY
	CMPA	#2
	BNE	KILLPLAY1
	LDX	PLYSTR1
	STX	PLYPOS1	;reset song chan 1 only
	LBRA	UPPLAY1
KILLPLAY1	CLR	PLAY
	LDX	PLYSTR1
	STX	PLYPOS1
	LDX	PLYSTR2
	STX	PLYPOS2
	RTS	;exit only play once actual exit
CHKCMD1	CMPA	#79	;o octave change
	BEQ	OCTCH1
	CMPA	#76	;length change
	BEQ	LENCH1
	CMPA	#80	;pause
	BEQ	PAUSE1
	CMPA	#72	;h
	BEQ	GMCTAT1
	CMPA	#86	;volume
	BEQ	VOLUMECH1
	LBRA	UPPLAY1	;not those commands
;
VOLUMECH1	LDA	,X+
	SUBA	#48
	LDY	#VOLUMETB
	LEAY	A,Y	;boom faster
	LDA	,Y
	STA	MAXVOL
	LBRA	UPPLAY1
;
; set octave channel 1
OCTCH1	LDA	,X+
	SUBA	#48	;asc 0
	STA	PLYOCT1
	LBRA	UPPLAY1
;
; set length channel 1
LENCH1	LDA	,X+
	SUBA	#48
	LDY	#NOTETB2
	LEAY	A,Y	;boom faster
	LDA	,Y
	STA	PLYLEN1
	LBRA	UPPLAY1
;
; set pause channel 1
PAUSE1	LDA	,X+
	SUBA	#48
	LDY	#NOTETB2
	LEAY	A,Y	;boom faster
	LDA	,Y
	STA	PLYDEL1
	STX	PLYPOS1
	LBRA	CHANNEL2	;no more data
;
GMCTAT1	LDA	PLAYSFX
	BNE	NOTATA1
	LDA	MAXVOL
	STA	VOL3
	LDA	#15
	SUBA	VOL3
	LDB	#10
	STB	YMREG
	STA	YMDATA	;set volume
; enable pcm
	LDA	#7
	STA	YMREG
	LDA	#28
	STA	YMDATA
	LDA	,X+
	SUBA	#48
	CMPA	#1
	BNE	GMCLOW1
	CLR	SLEN3
	CLR	SCNT3
	LDA	#6
	STA	YMREG
	LDA	#31
	STA	YMDATA
;	LDA	#230
;	STA	$FF41	;set possibly?
	LBRA	UPPLAY1
GMCLOW1	CLR	SLEN3
	CLR	SCNT3
; try diff period
	LDA	#6
	STA	YMREG
	LDA	#5
	STA	YMDATA
;	LDA	#228
;	STA	$FF41
	LBRA	UPPLAY1
NOTATA1	LDA	,X+
	LBRA	UPPLAY1
;
;
;
CHANNEL2	LDA	PLYDEL2
	CMPA	#1
	BLS	UPLP2	;good to go
	DEC	PLYDEL2
	RTS	;is paused
UPLP2	LDA	PLYENC2
	CMPA	#1
	BLS	UPPLAY02	;good to go
	DEC	PLYENC2
	RTS	;not ready
UPPLAY02	LDX	PLYPOS2
UPPLAY2	LDA	,X+	;grab command
; process string
	CMPA	#65
	BLO	NOTMUSIC2
	CMPA	#71
	BHI	NOTMUSIC2
; ok its a music tone
;
	SUBA	#65	0-11
; no hash tag
	LDY	#NOTETB1	;table for tones
	LEAY	A,Y	;get tone
	LDA	,Y	;tone loaded
; hash tag ?
	LDB	,X	;no advance
	CMPB	#35	;#
	BNE	NOHASH2
	INCA	;has a hash tag
	LEAX	1,X	;advance it
; load octave with it
NOHASH2	CMPB	#45
	BNE	NODECH2
	DECA	;has a -
	LEAX	1,X	;move player
NODECH2	STA	NOTE
	LDA	#12
	LDB	PLYOCT2
;	SUBB	#2
	MUL
	SUBD	#10	;calibration
	LDY	#PSGDAT
	LEAY	D,Y
	LEAY	D,Y
; ok set the note
	LDA	NOTE
	LEAY	A,Y
	LEAY	A,Y	;twice
	LDA	,Y+
; setup tone period
	LDB	#3
	STB	YMREG
	STA	YMDATA
	LDA	,Y	;next part
	DECB
	STB	YMREG
	STA	YMDATA	;tone set
	LDA	MAXVOL
	STA	VOL2
	LDA	#15
	SUBA	VOL2
	LDB	#9
	STB	YMREG
	STA	YMDATA	;set volume
	LDA	PLYLEN2
	STA	PLYENC2	;counter set
	LSRA
	STA	SLEN2	;smooth sound delay
	STA	SCNT2	;counter set
	STX	PLYPOS2	;save position
	RTS
; exit
;
;
NOTMUSIC2	CMPA	#0
	BNE	CHKCMD2
	LDX	PLYSTR2
	STX	PLYPOS2	;reset song
	LBRA	UPPLAY2
CHKCMD2	CMPA	#79	;o octave change
	BEQ	OCTCH2
	CMPA	#76	;length change
	BEQ	LENCH2
	CMPA	#80	;pause
	BEQ	PAUSE2
	CMPA	#72	;h
	BEQ	GMCTAT2
	CMPA	#86	;volume
	BEQ	VOLUMECH2
	LBRA	UPPLAY2	;not those commands
;
VOLUMECH2	LDA	,X+
	SUBA	#48
	LDY	#VOLUMETB
	LEAY	A,Y	;boom faster
	LDA	,Y
	STA	MAXVOL
	LBRA	UPPLAY2
;
; set octave channel 1
OCTCH2	LDA	,X+
	SUBA	#48	;asc 0
	STA	PLYOCT2
	LBRA	UPPLAY2
;
; set length channel 1
LENCH2	LDA	,X+
	SUBA	#48
	LDY	#NOTETB2
	LEAY	A,Y	;boom faster
	LDA	,Y
	STA	PLYLEN2
	LBRA	UPPLAY2
;
; set pause channel 1
PAUSE2	LDA	,X+
	SUBA	#48
	LDY	#NOTETB2
	LEAY	A,Y	;boom faster
	LDA	,Y
	STA	PLYDEL2
	STX	PLYPOS2
	RTS	;no more data
;
GMCTAT2	LDA	PLAYSFX
	BNE	NOTATA2
	LDA	MAXVOL
	STA	VOL3
	LDA	#15
	SUBA	VOL3
	LDB	#10
	STB	YMREG
	STA	YMDATA	;set volume
; enable pcm
	LDA	#7
	STA	YMREG
	LDA	#28
	STA	YMDATA
	LDA	,X+
	SUBA	#48
	CMPA	#1
	BNE	GMCLOW2
	CLR	SLEN3
	CLR	SCNT3
	LDA	#6
	STA	YMREG
	LDA	#31
	STA	YMDATA
;	LDA	#230
;	STA	$FF41	;set possibly?
	LBRA	UPPLAY2
GMCLOW2	CLR	SLEN3
	CLR	SCNT3
; try diff period
	LDA	#6
	STA	YMREG
	LDA	#5
	STA	YMDATA
;	LDA	#228
;	STA	$FF41
	LBRA	UPPLAY2
NOTATA2	LDA	,X+
	LBRA	UPPLAY2
; ********************************************************SFX PLAYER ***********************************************************
SFXPLAY	LDA	PLAYSFX
	BNE	PLAYSN	;check play routine
	RTS	;no music
PLAYSN	LDA	PLYSFXCNT
	BEQ	UPPLAY9
	DEC	PLYSFXCNT
	RTS	;not ready to play
;
UPPLAY9	LDA	PLYSFXSPD
	STA	PLYSFXCNT	;delay reset
CHANNEL9	LDA	PLYSFXDEL
	CMPA	#1
	BLS	UPLP9	;good to go
	DEC	PLYSFXDEL
	RTS
UPLP9	LDA	PLYSFXENC
	CMPA	#1
	BLS	UPPLAY09	;good to go
	DEC	PLYSFXENC
	RTS
UPPLAY09	LDX	PLYSFXPOS
UPPLAYY9	LDA	,X+	;grab command
; process string
	CMPA	#65
	BLO	NOTMUSIC9
	CMPA	#71
	BHI	NOTMUSIC9
; ok its a music tone
;
	SUBA	#65	0-11
; no hash tag
	LDY	#NOTETB1	;table for tones
	LEAY	A,Y	;get tone
	LDA	,Y	;tone loaded
; hash tag ?
	LDB	,X	;no advance
	CMPB	#35	;#
	BNE	NOHASH9
	INCA	;has a hash tag
	LEAX	1,X	;advance it
; load octave with it
NOHASH9	CMPB	#45
	BNE	NODECH9
	DECA	;has a -
	LEAX	1,X	;move player
NODECH9	STA	NOTE
	LDA	#12
	LDB	PLYSFXOCT
;	SUBB	#2
	MUL
	SUBD	#10	;calibration
	LDY	#PSGDAT
	LEAY	D,Y
	LEAY	D,Y
; ok set the note
	LDA	NOTE
	LEAY	A,Y
	LEAY	A,Y	;twice
	LDA	,Y+
; setup tone period
	LDB	#5
	STB	YMREG
	STA	YMDATA
	LDA	,Y	;next part
	DECB
	STB	YMREG
	STA	YMDATA	;tone set
	LDA	MAXSFXVOL
	STA	VOL3
	LDA	#15
	SUBA	VOL3
	LDB	#10
	STB	YMREG
	STA	YMDATA	;set volume
; now lets disable pcm and only have music
	LDA	#7
	STA	YMREG
	LDA	#56
	STA	YMDATA	;enable music and disable pcm
	LDA	PLYSFXLEN
	STA	PLYSFXENC	;counter set
	LSRA
	STA	SLEN3	;smooth sound delay
	STA	SCNT3	;counter set
	STX	PLYSFXPOS	;save position
	RTS
NOTMUSIC9	CMPA	#0	
	BNE	CHKCMD9
	LDA	PLAYSFX
	CMPA	#2
	BNE	KILLPLAY9
	LDX	PLYSFXSTR
	STX	PLYSFXPOS	;reset song chan 1 only
	LBRA	UPPLAYY9
KILLPLAY9	CLR	PLAYSFX
	LDX	PLYSFXSTR
	STX	PLYSFXPOS
	RTS	;exit only play once actual exit
CHKCMD9	CMPA	#79	;o octave change
	BEQ	OCTCH9
	CMPA	#76	;length change
	BEQ	LENCH9
	CMPA	#80	;pause
	BEQ	PAUSE9
	CMPA	#72	;h
	BEQ	GMCTAT9
	CMPA	#86	;volume
	BEQ	VOLUMECH9
	LBRA	UPPLAYY9
;
VOLUMECH9	LDA	,X+
	SUBA	#48
	LDY	#VOLUMETB
	LEAY	A,Y	;boom faster
	LDA	,Y
	STA	MAXSFXVOL
	LBRA	UPPLAYY9
;
; set octave channel 1
OCTCH9	LDA	,X+
	SUBA	#48	;asc 0
	STA	PLYSFXOCT
	LBRA	UPPLAYY9
;
; set length channel 1
LENCH9	LDA	,X+
	SUBA	#48
	LDY	#NOTETB2
	LEAY	A,Y	;boom faster
	LDA	,Y
	STA	PLYSFXLEN
	LBRA	UPPLAYY9
;
; set pause channel 1
PAUSE9	LDA	,X+
	SUBA	#48
	LDY	#NOTETB2
	LEAY	A,Y	;boom faster
	LDA	,Y
	STA	PLYSFXDEL
	STX	PLYSFXPOS
	RTS	;no more data
;
; now lets disable pcm and only have music
GMCTAT9	LDA	#7
	STA	YMREG
	LDA	#28
	STA	YMDATA	;enable pcm and disable music
	LDA	MAXSFXVOL
	STA	VOL3
	LDA	#15
	SUBA	VOL3
	LDB	#10
	STB	YMREG
	STA	YMDATA	;volume set
	LDA	,X+
	SUBA	#48
	CMPA	#1
	BNE	GMCLOW9
	CLR	SLEN3
	CLR	SCNT3
; try diff period
	LDA	#6
	STA	YMREG
	LDA	#31
	STA	YMDATA
;	LDA	#230
;	STA	$FF41	;set possibly?
	LBRA	UPPLAYY9
GMCLOW9	CLR	SLEN3
	CLR	SCNT3
; try diff period
	LDA	#6
	STA	YMREG
	LDA	#5
	STA	YMDATA
;	LDA	#228
;	STA	$FF41
	LBRA	UPPLAYY9
ENDFUNCTION
